/*
 * ============================================================================
 *
 *       Filename:  message.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2015年03月03日 10时07分51秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * ============================================================================
 */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>

#include "arg.h"
#include "common.h"
#include "thread.h"
#include "sockarr.h"
#include "process.h"
#include "message.h"

void message_insert(struct ap_hash_t *aphash, struct message_t *msg)
{
	assert(aphash != NULL);
	sys_debug("message insert aphash: %p, msg: %p\n", aphash, msg);

	LOCK(&aphash->msglock);
	list_add_tail(&msg->list, &aphash->msghead);
	UNLOCK(&aphash->msglock);
}

static void message_free(struct message_t *msg)
{
	switch(msg->proto) {
	case MSG_PROTO_TCP:
		free(msg->data);
	case MSG_PROTO_ETH:
		free(msg);
		break;
	default:
		panic();
	}
}

static void message_delete(struct ap_hash_t *aphash)
{
	struct message_t *msg, *m1;

	LOCK(&aphash->msglock);
	list_for_each_entry_safe(msg, m1,
		&aphash->msghead, list) {
		msg_proc(aphash, (void *)msg->data, 
			msg->len, msg->proto);
		list_del(&msg->list);
		message_free(msg);
	}
	UNLOCK(&aphash->msglock);
}

static void *message_travel(void *arg)
{
	assert(aphead != NULL);

	struct ap_hash_head_t *bucket;
	struct ap_hash_t *aphash;
	struct hlist_node *p1;

	/* die loop */
	int i;
	while(1) {
		sleep(args_info.msgitv_arg);

		/* travel hash bucket */
		for(i = 0; i < MAX_BUCKET; i++) {
			bucket = &aphead[i];

			/* travel aphash list */
			hlist_for_each_entry(aphash, p1, 
				&bucket->head, node) {
				/* travel message */
				message_delete(aphash);
			}
		}
	}
}

void message_init()
{
	pthread_create_detach(message_travel, NULL);
	sys_info("MODULE: message travel success\n");
}

